<?php
namespace Infinity;

abstract class Term {
  /**
   * @param $tid
   * @return mixed
   */
  public static function getParents($tid) {
    $static = &drupal_static(__CLASS__.__FUNCTION__, array());
    if(!isset($static[$tid])) {
      if(is_numeric($tid))
        $term = taxonomy_term_load($tid);
      elseif(is_object($tid))
        $term = $tid;
      $parents = array($term);
      while($term_parent = taxonomy_get_parents($term->tid)) {
        $term = array_pop($term_parent);
        $parents []= $term;
      }
      $static[$tid] = $parents;
    }
    return $static[$tid];
  }

  /**
   * @param $tid
   * @param int|string $vid
   * @param int $max_level
   * @return mixed
   */
  public static function getChildren($tid, $vid=0, $max_level=3) {
    $static = &drupal_static(__CLASS__.__FUNCTION__, array());
    if(!isset($static[$tid][$vid])) {
      $tmp = array();
      if(is_string($vid)) {
        $voc = taxonomy_vocabulary_machine_name_load($vid);
        $vid = $voc->vid;
      }
      $children = self::_getChildren($tid, $vid);
      foreach($children as $child) {
        $tmp[]= $child;
        if($max_level > 1) {
          $child_data = self::getChildren($child->tid, $vid, $max_level-1);
          $tmp = array_merge($tmp, $child_data);
        }
      }
      $data = array();
      foreach($tmp as $child) {
        $data[$child->tid] = $child;
      }
      unset($tmp);
      $static[$tid][$vid] = $data;
    }
    return $static[$tid][$vid];
  }

  /**
   * @param $tid
   * @param int $vid
   * @return array
   */
  private static function _getChildren($tid, $vid = 0) {

    $query = db_select('taxonomy_term_data', 't');
    $query->join('taxonomy_term_hierarchy', 'h', 'h.tid = t.tid');
    $query->addField('t', 'tid');
    $query->condition('h.parent', $tid);
    if ($vid) {
      $query->condition('t.vid', $vid);
    }
    $query->addTag('term_access');
    $query->orderBy('t.weight');
    $query->orderBy('t.name');
    $tids = $query->execute()->fetchCol();
    return taxonomy_term_load_multiple($tids);
  }
}